package io.renren.modules.workmanagement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.sys.entity.SysRoleEntity;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.service.SysRoleService;
import io.renren.modules.sys.service.SysUserRoleService;
import io.renren.modules.sys.service.SysUserService;
import io.renren.modules.workmanagement.dao.StudentDao;
import io.renren.modules.workmanagement.entity.DepartmentEntity;
import io.renren.modules.workmanagement.entity.StudentEntity;
import io.renren.modules.workmanagement.enums.RoleEnums;
import io.renren.modules.workmanagement.service.DepartmentService;
import io.renren.modules.workmanagement.service.StudentService;
import io.renren.modules.workmanagement.utils.PojoUtils;
import io.renren.modules.workmanagement.vo.AddStudentVO;
import io.renren.modules.workmanagement.vo.BatchAddStudentVO;
import io.renren.modules.workmanagement.vo.StudentVO;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service("studentService")
public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> implements StudentService {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private DepartmentService departmentService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<StudentEntity> page = this.page(
                new Query<StudentEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addStudent(AddStudentVO addStudentVO, Long userId) {
        SysUserEntity existUser = sysUserService.getByUsername(addStudentVO.getStuNo());
        if (existUser == null) {
            SysRoleEntity role = sysRoleService.getByRoleName(RoleEnums.Student.getRoleName());
            existUser = new SysUserEntity();
            existUser.setName(addStudentVO.getStuName());
            existUser.setUsername(addStudentVO.getStuNo().toString());
            existUser.setPassword("123456");
            existUser.setStatus(1);
            existUser.setRoleIdList(Arrays.asList(role.getRoleId()));
            existUser.setCreateUserId(userId);
            existUser.setCreateTime(new Date());
            //sha256加密
            String salt = RandomStringUtils.randomAlphanumeric(20);
            existUser.setPassword(new Sha256Hash(existUser.getPassword(), salt).toHex());
            existUser.setSalt(salt);

            sysUserService.save(existUser);
            sysUserRoleService.saveOrUpdate(existUser.getUserId(), existUser.getRoleIdList());
        }


        DepartmentEntity department = departmentService.getByAdminId(userId);
        StudentEntity studentEntity = this.getByUserId(existUser.getUserId());
        if (studentEntity != null) {
            if (studentEntity.getClassId().equals(addStudentVO.getClassId())) {
                throw new RRException("该学生已经在当前班级中");
            }
            throw new RRException("该学生已经在其他班级存在");
        }

        studentEntity = new StudentEntity();
        studentEntity.setUserId(existUser.getUserId());
        studentEntity.setClassId(addStudentVO.getClassId());
        studentEntity.setDepartmentId(department.getId());
        this.save(studentEntity);

    }

    @Override
    public List<StudentEntity> getListByClassIds(List<Long> classIds) {
        return this.lambdaQuery().in(StudentEntity::getClassId, classIds).list();
    }

    @Override
    public void updateStudent(AddStudentVO addStudentVO) {
        Long stuNo = addStudentVO.getStuNo();
        SysUserEntity sysUser = sysUserService.getByUsername(stuNo);
        sysUser.setUsername(addStudentVO.getStuNo().toString());
        sysUser.setName(addStudentVO.getStuName());
        Optional.ofNullable(addStudentVO).map(AddStudentVO::getPassword).ifPresent(password -> {
            String salt = RandomStringUtils.randomAlphanumeric(20);
            sysUser.setSalt(salt);
            sysUser.setPassword(new Sha256Hash(password, salt).toHex());
        });
        sysUserService.updateById(sysUser);
    }

    @Override
    public void deleteStudent(Long stuNo, Long classId) {
        SysUserEntity sysUserEntity = sysUserService.getByUsername(stuNo);
        this.lambdaUpdate()
                .eq(StudentEntity::getUserId, sysUserEntity.getUserId())
                .eq(StudentEntity::getClassId, classId)
                .remove();
    }

    @Override
    public StudentEntity getByUserId(Long userId) {
        return this.lambdaQuery().eq(StudentEntity::getUserId, userId).one();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchAddStudent(BatchAddStudentVO batchAddStudentVO, Long userId) {
        Long classId = batchAddStudentVO.getClassId();
        if(classId == null){
            throw new RRException("请选择班级");
        }
        List<AddStudentVO> students = batchAddStudentVO.getStudents();
        students.stream().forEach(item -> {
            item.setClassId(classId);
            this.addStudent(item,userId);
        });
    }

    @Override
    public List<StudentVO> getListByClassId(Long calssId) {
        List<StudentEntity> list = this.lambdaQuery().eq(StudentEntity::getClassId, calssId).list();
        List<Long> userIds = PojoUtils.streamMapList(list, StudentEntity::getUserId);
        List<SysUserEntity> userEntityList = sysUserService.listByIds(userIds);
        Map<Long, SysUserEntity> map = PojoUtils.listToMap(userEntityList, SysUserEntity::getUserId, Function.identity());
        return list.stream().map(item -> {
            SysUserEntity sysUserEntity = map.get(item.getUserId());
            StudentVO studentVO = new StudentVO();
            studentVO.setId(item.getId());
            studentVO.setStuNo(Long.parseLong(sysUserEntity.getUsername()));
            studentVO.setStuName(sysUserEntity.getName());
            studentVO.setMobili(sysUserEntity.getMobile());
            studentVO.setEmail(sysUserEntity.getEmail());
            studentVO.setStatus(sysUserEntity.getStatus());
            studentVO.setClassId(calssId);
            return studentVO;
        }).collect(Collectors.toList());
    }

    @Override
    public void removeByClassIds(List<Integer> asList) {
        this.lambdaUpdate().in(StudentEntity::getClassId, asList).remove();
    }
}
